package org.hades.corelib.utils

import android.app.Activity
import android.app.Application
import android.content.Context
import android.os.Bundle
import android.os.Process
import androidx.annotation.Nullable
import java.util.*


/**
 * inject application context , to provider other utils
 */
object AppUtils {
    const val FILE_PROVIDER = ".commutils.provider"
    private const val BUGLY_PACKAGE = "tencent.bugly"
    private var mApplication: Application? = null
    private var activityStack: Stack<Activity>? = null

    /**
     * Init AppUtils
     * if use bugly after init
     * @param context context
     */
    fun init(context: Context) {
        init(context.getApplicationContext() as Application)
    }

    /**
     * Init AppUtils
     * if use bugly after init，if crash close app
     * @param application application
     */
    fun init(application: Application) {
        mApplication = application
        activityStack = Stack()
        mApplication?.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
            override fun onActivityCreated(activity: Activity, @Nullable savedInstanceState: Bundle?) {
                activityStack!!.push(activity)
            }

            override fun onActivityStarted(activity: Activity) {}
            override fun onActivityResumed(activity: Activity) {}
            override fun onActivityPaused(activity: Activity) {}
            override fun onActivityStopped(activity: Activity) {}
            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
            override fun onActivityDestroyed(activity: Activity) {
                activityStack!!.remove(activity)
            }
        })
        Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler())
    }

    /**
     * get the context of Application Object
     *
     * @return the context
     */
    val app: Application?
        get() {
            if (null == mApplication) throw NullPointerException("you should init first")
            return mApplication
        }

    private class UncaughtExceptionHandler : Thread.UncaughtExceptionHandler {
        var handler: Thread.UncaughtExceptionHandler?
        override fun uncaughtException(t: Thread, e: Throwable) {
            val iterator: Iterator<Activity> = activityStack!!.iterator()
            while (iterator.hasNext()) {
                val next = iterator.next()
                next.finish()
            }
            if (handler != null && handler!!.javaClass.name.contains(BUGLY_PACKAGE)) handler!!.uncaughtException(
                t,
                e
            ) else {
                Process.killProcess(Process.myPid())
                System.exit(1)
            }
            System.gc()
        }

        init {
            handler = Thread.getDefaultUncaughtExceptionHandler()
        }
    }
}